
package com.dcivision.rules.core;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mandarax.kernel.Predicate;
import org.mandarax.kernel.Session;
import org.mandarax.kernel.Term;
import org.mandarax.lib.text.BinaryStringPredicate;

/**
 * Class serving predicates and functions needed for text (String) arithmetic.
 * @author <A href="http://www-ist.massey.ac.nz/JBDietrich" target="_top">Jens Dietrich</A>
 * @version 3.4 <7 March 05>
 * @since 1.4
 */
public class StringArithmetic {
  protected Log log = LogFactory.getLog(this.getClass().getName());
  //####################################################################
  // Add by Tony.Chen,  Date: 11/08/2005
  // 
  // For handle String include anther String
  // e.g
  //    String s1 = "1,2,3,4,5,6,7,8";
  //    String s2 = "3,6";
  //    containsArray(s1, s2) return true
  //####################################################################
  public static final Predicate CONTAINS_ARRAY  =
  	new StringArithmetic.ContainsArray ();
  
  public static class ContainsArray extends BinaryStringPredicate {
  	
  	public String getName() {
  		return "containsArray";
  	}
  	
  	public Object perform(Term[] parameter,Session session) throws IllegalArgumentException, UnsupportedOperationException {
  		String s1, s2;
  		boolean result = false;
  		try {
  			s1 = (String) (parameter[0].resolve (session));
  			s2 = (String) (parameter[1].resolve (session));
  			
  			String[] itemArray1 = s1.split(",");
  			String[] itemArray2 = s2.split(",");
  			
  			for (int i = 0; i < itemArray2.length; i++ ) {
  				
  				boolean included = false;
  				for (int j = 0; j < itemArray1.length; j++ ) {
  					String temp1 = itemArray1[j];
  					String temp2 = itemArray2[i];
  					
  					included = evaluate(temp1, temp2);
  					if(included){
  						break;
  					}
  				}
//  		if included ==true then	result = included  ;
          if(included){
            result = included;
            break;
          }
  			}   
  		} catch(Exception x) {
  			throw new IllegalArgumentException ();
  		}
  		
  		if(s1 == null) {
  			throw new IllegalArgumentException ();
  		}
  		
  		return result ? Boolean.TRUE : Boolean.FALSE;
  	}
  	
  	public boolean evaluate(String s1, String s2) {
      if ( s2.indexOf(":") == -1) {
        return s1.indexOf(s2) > -1;
      }
  		return s1.equals(s2);
  	}
  };
  
  //####################################################################
  
  /**
   * Create a contain equals predicate
   */
  public static final Predicate CONTAIN_EQUALS  =
  	new StringArithmetic.ContainEauqls ();
  
  /**
   * The class use to check the whether getCCEmailAddressAndUserIDGroupIDRoleID() only include 
   * the information fo a user
   * e.g.
   *    "tonyChan@dcivision.com,U:1,G:1,R:1"  ContainEquals "U:1"  return true.
   *    "tonyChan@dcivision.com,U:1,G:1,R:1,PeterChan@dcivision.com,U:2,G:2,R:2"  ContainEquals "U:1"  return false. 
   */
  public static class ContainEauqls extends BinaryStringPredicate {
  	
  	public String getName() {
  		return "containEauqls";
  	}
  	
  	public Object perform(Term[] parameter,Session session) throws IllegalArgumentException, UnsupportedOperationException {
  		String s1, s2;
  		boolean result = true;
  		try {
  			s1 = (String) (parameter[0].resolve (session));
  			s2 = (String) (parameter[1].resolve (session));
  			
        //judge whether exist "@"
        if ( s1.indexOf("@") > -1) {
          String[] tempArr = s1.split("@");
          String[] itemArray1 = s1.split(",");
          String[] itemArray2 = s2.split(",");
          
          //judge whether the count of email address equals the count of the selected user
          if ( (tempArr.length -1) == itemArray2.length ) {
            for (int i = 0; i < itemArray2.length; i++ ) {
              
              boolean included = false;
              for (int j = 0; j < itemArray1.length; j++ ) {
                String temp1 = itemArray1[j];
                String temp2 = itemArray2[i];
                
                included = evaluate(temp1, temp2);
                if(included){
                  break;
                }
              }
              result = result && included;
            }   
          } else {
            result = false;
          }
        	
        } else {
          result = false;
        }
  		} catch(Exception x) {
  			throw new IllegalArgumentException ();
  		}
  		
  		if(s1 == null) {
  			throw new IllegalArgumentException ();
  		}
  		
  		return result ? Boolean.TRUE : Boolean.FALSE;
  	}
  	
  	public boolean evaluate(String s1, String s2) {
  		return s1.equals(s2);
  	}
  };

}
